package models

import (
	"gitee.com/sansaniot/ssiot-core/httpmvc/model"
	"ssdevice/common/dto"
	"ssdevice/internal/device/models/query"
)

type SysTag struct {
	Id         string         `json:"id"`
	Name       string         `json:"name"`
	CreateTime *dto.LocalTime `json:"createTime"`
	UpdateTime *dto.LocalTime `json:"-"`
	model.Model
}

func (e *SysTag) TableName() string {
	return "sys_tag"
}

func (e *SysTag) Create() error {
	return e.Orm.Create(e).Error
}

func (e *SysTag) Update() error {
	return e.Orm.Model(e).Where("id = ?", e.Id).Updates(e).Omit("create_time").Error
}

func (e *SysTag) Delete() error {
	return e.Orm.Where("id = ?", e.Id).Delete(e).Error
}

// 批量删除
func (e *SysTag) BatchDelete(ids []string) error {
	return e.Orm.Where("id IN ?", ids).Delete(e).Error
}

// FindPage 获取标签分页列表
func (e *SysTag) FindPage(q *query.SysTagQuery) (result []*SysTag, count int64, err error) {
	list := make([]*SysTag, 0)
	where := dto.MakeCondition(q.GetNeedSearch())

	err = e.Orm.Model(e).Scopes(
		where,
		dto.OrderDest("create_time", true, q.OrderBy),
		dto.Paginate(q.GetPageSize(), q.GetPageIndex()),
	).Find(&list).Limit(-1).Offset(-1).Count(&count).Error

	return list, count, nil
}

// CreateOrGetByName 创建标签，如果标签名已存在则返回已存在标签的ID
func (e *SysTag) CreateOrGetByName() (string, error) {
	// 检查标签名称是否已存在
	existingTag := &SysTag{}
	err := e.Orm.Where("name = ?", e.Name).First(existingTag).Error
	if err == nil {
		// 标签名已存在，直接返回已存在标签的ID
		return existingTag.Id, nil
	}

	// 标签不存在，创建新标签
	err = e.Create()
	if err != nil {
		return "", err
	}
	return e.Id, nil
}

// ... 其他方法 ...

func (e *SysTag) GetTagDeviceStats(tagName string, tagTotal int, username string, deptIn []string) (map[string]interface{}, error) {
	// 1. 查找具有指定标签的所有设备
	var deviceSns []string
	var err error

	if username != "admin" {
		err = e.Orm.Raw(`
        SELECT DISTINCT tr.device_sn 
        FROM sys_dev_tag_r tr
        JOIN sys_tag t ON tr.tag_id = t.id
        JOIN sys_dev d ON tr.device_sn = d.sn
        WHERE t.name = ?
        AND d.dept_id IN (?)
    `, tagName, deptIn).Scan(&deviceSns).Error
	} else {
		err = e.Orm.Raw(`
        SELECT DISTINCT tr.device_sn 
        FROM sys_dev_tag_r tr
        JOIN sys_tag t ON tr.tag_id = t.id
        JOIN sys_dev d ON tr.device_sn = d.sn
        WHERE t.name = ?
    `, tagName).Scan(&deviceSns).Error
	}

	if err != nil {
		return nil, err
	}

	result := make(map[string]interface{})

	if len(deviceSns) == 0 {
		result["total"] = 0
		result["online"] = 0
		result["tags"] = make(map[string]struct {
			Total  int `json:"total"`
			Online int `json:"online"`
		})
		return result, nil
	}

	// 2. 获取所有设备总数和在线总数
	var totalStats struct {
		Total  int `json:"total"`
		Online int `json:"online"`
	}
	err = e.Orm.Raw(`
        SELECT 
            COUNT(*) AS total,
            SUM(CASE WHEN online_status = 'online' THEN 1 ELSE 0 END) AS online
        FROM sys_dev
        WHERE sn IN (?)
    `, deviceSns).Scan(&totalStats).Error
	if err != nil {
		return nil, err
	}

	// 3. 统计这些设备的其他标签的设备总数和在线数量
	var tagStats []struct {
		TagName string
		Total   int
		Online  int
	}

	err = e.Orm.Raw(`
        SELECT 
            t.name AS tag_name, 
            COUNT(DISTINCT tr.device_sn) AS total,
            SUM(CASE WHEN d.online_status = 'online' THEN 1 ELSE 0 END) AS online
        FROM sys_dev_tag_r tr
        JOIN sys_tag t ON tr.tag_id = t.id
        JOIN sys_dev d ON tr.device_sn = d.sn
        WHERE tr.device_sn IN (?) AND t.name != ?
        GROUP BY t.name
    `, deviceSns, tagName).Scan(&tagStats).Error
	if err != nil {
		return nil, err
	}

	// 4. 组装返回结果
	tags := make(map[string]struct {
		Total  int     `json:"total"`
		Online int     `json:"online"`
		Rate   float64 `json:"rate"`
	})
	for _, stat := range tagStats {

		rate := 0.0
		if tagTotal > 0 {
			rate = float64(stat.Total) / float64(tagTotal) * 100
		}

		tags[stat.TagName] = struct {
			Total  int     `json:"total"`
			Online int     `json:"online"`
			Rate   float64 `json:"rate"`
		}{
			Total:  stat.Total,
			Online: stat.Online,
			Rate:   rate,
		}
	}

	result["total"] = totalStats.Total
	result["online"] = totalStats.Online
	result["resultTags"] = tags
	result["searchTag"] = tagName

	if tagTotal > 0 {
		result["rate"] = float64(totalStats.Total) / float64(tagTotal) * 100
	} else {
		result["rate"] = 0
	}

	return result, nil
}

// ... 其他方法 ...
